package cc.z8g.browser.core

import android.app.Activity
import cc.z8g.browser.core.tab.TabModel
import cc.z8g.browser.core.tab.TabViewState
import cc.z8g.browser.database.Bookmark
import cc.z8g.browser.database.HistoryEntry
import cc.z8g.browser.ssl.SslCertificateInfo
import cc.z8g.browser.core.tab.TabCreator
import android.content.Intent
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import cc.z8g.browser.core.view.LongPress

/**
 * The contract for the browser.
 */
interface BrowserContract {

    /**
     * The view that renders the browser state.
     */
    interface View {

        /**
         * Render the [viewState] for the current tab in the browser.
         */
        fun renderState(viewState: BrowserViewState)

        /**
         * Render the [tabs] in the tabs list.
         */
        fun renderTabs(tabs: List<TabViewState>)

        /**
         * Show the dialog to add a bookmark for the current page.
         *
         * @param title The current title of the page.
         * @param url The current URL of the page.
         * @param folders The available folders that the bookmark can be moved to.
         */
        fun showAddBookmarkDialog(title: String, url: String, folders: List<String>)

        /**
         * Show the options dialog for the provided [bookmark].
         */
        fun showBookmarkOptionsDialog(bookmark: Bookmark.Entry)

        /**
         * Show the dialog to edit a bookmark.
         *
         * @param title The current title of the bookmark.
         * @param url The current URL of the bookmark.
         * @param folder The current folder the bookmark is in.
         * @param folders The available folders that the bookmark can be moved to.
         */
        fun showEditBookmarkDialog(
            title: String,
            url: String,
            folder: String,
            folders: List<String>
        )

        /**
         * Show the options dialog for the provided [folder].
         */
        fun showFolderOptionsDialog(folder: Bookmark.Folder)

        /**
         * Show the edit folder dialog for the folder with the provided [title].
         */
        fun showEditFolderDialog(title: String)

        /**
         * Show the options dialog for the provided [historyEntry].
         */
        fun showHistoryOptionsDialog(historyEntry: HistoryEntry)

        /**
         * Show the dialog that allows the user to search the web page for a query.
         */
        fun showFindInPageDialog()

        /**
         * Show the options menu for long pressing a link in the web page.
         */
        fun showLinkLongPressDialog(longPress: LongPress)

        /**
         * Show the options menu for long pressing an image in the web page.
         */
        fun showImageLongPressDialog(longPress: LongPress)

        /**
         * Show the informational dialog about the SSL certificate info.
         */
        fun showSslDialog(sslCertificateInfo: SslCertificateInfo)

        /**
         * Show the close browser dialog for the dialog with the provide [id].
         */
        fun showCloseBrowserDialog(id: Int)

        /**
         * Open the bookmark drawer if it is closed.
         */
        fun openBookmarkDrawer()

        /**
         * Close the bookmark drawer if it is open.
         */
        fun closeBookmarkDrawer()

        /**
         * Open the tab drawer if it is closed.
         */
        fun openTabDrawer()

        /**
         * Close the tab drawer if it is open.
         */
        fun closeTabDrawer()

        /**
         * Show the toolbar/search box if it has been hidden due to scrolling.
         */
        fun showToolbar()

        /**
         * Show a warning to the user that they are about to open a local file in the browser that
         * could be potentially dangerous.
         */
        fun showLocalFileBlockedDialog()

        /**
         * Show the file chooser with the provided [intent].
         */
        fun showFileChooser(intent: Intent)

        /**
         * Show a custom [view] over everything that will play a video.
         */
        fun showCustomView(view: android.view.View)

        /**
         * Hide the custom view that was previously shown by calling [showCustomView].
         */
        fun hideCustomView()

        /**
         * Clear focus from the search view if it has focus.
         */
        fun clearSearchFocus()

        fun getActivity(): Activity
    }

    /**
     * The model used to manage tabs in the browser.
     */
    interface Model {

        /**
         * Delete the tab with the provided [id].
         */
        fun deleteTab(id: Int): Completable

        /**
         * Delete all open tabs.
         */
        fun deleteAllTabs(): Completable

        /**
         * Create a tab that will be initialized with the [tabCreator].
         */
        fun createTab(tabCreator: TabCreator): Single<TabModel>

        /**
         * Reopen the most recently closed tab if there is a closed tab to re-open.
         */
        fun reopenTab(): Maybe<TabModel>

        /**
         * Select the tab with the provide [id] as the currently viewed tab.
         */
        fun selectTab(id: Int): TabModel

        /**
         * Initialize all tabs that were previously frozen when the browser was last open, and
         * initialize any tabs that should be opened from the initial browser action.
         */
        fun initializeTabs(): Maybe<List<TabModel>>

        /**
         * Notifies the model that all tabs need to be frozen before the browser shuts down.
         */
        fun freeze()

        /**
         * Clean all permanent stored content.
         */
        fun clean()

        /**
         * The current open tabs.
         */
        val tabsList: List<TabModel>

        /**
         * Changes to the current open tabs.
         */
        fun tabsListChanges(): Observable<List<TabModel>>

    }
    /**
     * Supported actions that can be passed to the browser.
     */
    sealed class Action {
        /**
         * The action to load the provided [url].
         */
        data class LoadUrl(val url: String) : Action()

        /**
         * The action to emergency clean the entire browser contents and stored data.
         */
        object Panic : Action()
    }

}
